#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@Time    : 2025/4/15 上午9:59
@Author  : Suger
@File    : bridge.py
@Desc    : 
"""
import os
import json
import platform
from PyQt5.QtCore import QSettings
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QUrl, Qt

from worker import *
from utils.load_file import *
from utils.tools import resource_path
from log import log

headers = {"Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QxIiwidWlkIjoiOGU0NGJiNGY4OTkyOWFiMiIsImlkIjo0LCJ0eXBlIjoibWluaSIsImV4cCI6MTc0NTgyODk0M30.hnvUB2mgPbCAC29DwT4z9lSB6XqNe0Bogx0NQeYCkHM"}


class Bridge(QObject):
    started = pyqtSignal(str)
    finished = pyqtSignal(str)     # emit(result)
    failed = pyqtSignal(str)    # emit(exception)
    stopped = pyqtSignal(str)
    result = pyqtSignal(str)
    ident_result = pyqtSignal(str)
    ident_context_result = pyqtSignal(str)
    rewrite_result = pyqtSignal(str)
    source_result = pyqtSignal(str)
    get_setting = pyqtSignal(str, str)
    progress_signal = pyqtSignal(str, int)

    batch_ident_and_synthesis_result = pyqtSignal(str)
    select_files_result = pyqtSignal(str, list, int)
    select_folder_result = pyqtSignal(str, str)
    select_folder_normal_shot_path_input = pyqtSignal(str, int, str, str, int)
    auto_mix_folder_result = pyqtSignal(str, str, int, float, float, float)
    choose_single_ident_audio_file_result = pyqtSignal(str, str, float)
    load_audio_model_result = pyqtSignal(str)



    def __init__(self, view):
        super().__init__()
        self.current_thread = None
        self.view = view
        self.settings = QSettings("AiMix", "Config")
        self.progress_items = {}


    @pyqtSlot(str)
    def __init_user_info(self, data):
        """初始化headers"""
        # {
        #     "code": 1,
        #     "msg": "登录成功",
        #     "data": [
        #         {
        #             "username": "test1",
        #             "nickname": "武帝",
        #             "avatar": "",
        #             "phone": "",
        #             "amount": "788.00",
        #             "batches": "530.00",
        #             "uid": "8e44bb4f89929ab2",
        #             "level": "普通",
        #             "is_proxy": "是",
        #             "referrer_name": "proxy",
        #             "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QxIiwidWlkIjoiOGU0NGJiNGY4OTkyOWFiMiIsImlkIjo0LCJ0eXBlIjoibWluaSIsImV4cCI6MTc0NTU2OTI5NX0.ASHyw9Ete0zFqahDiEeWTsWoj5HWN4SsZMQy6_HnjQQ",
        #             "token_type": "bearer"
        #         }
        #     ]
        # }
        headers.update({
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {data["data"][0]["access_token"]}'
        })


    @pyqtSlot(str)
    def get(self, key):
         """获取配置"""
         self.get_setting.emit(key, self.settings.value(key))

    @pyqtSlot(str, str)
    def set(self, key, value):
        """设置配置"""
        self.settings.setValue(key, value)


    @pyqtSlot(str)
    def open_file(self, file_name):
        """打开文件/文件夹"""
        if platform.system() == 'Windows':
            os.startfile(file_name)
        elif platform.system() == 'Darwin':
            os.system('open ' + file_name)

    @pyqtSlot(str)
    def choose_single_ident_audio_file(self, eid):
        """单个音视频识别文件"""
        file_filter = "所有音视频文件 (*.mp4 *.mov *.avi *.mkv *.mp3 *.wav *.m4a *.acc);;MP4 文件 (*.mp4);;MOV 文件 (*.mov);;AVI 文件 (*.avi);;MKV 文件 (*.mkv);; MP3 文件 (*.mp3);; WAV 文件 (*.wav);; M4A 文件 (*.m4a);; ACC 文件 (*.acc)"
        file, _ = QFileDialog.getOpenFileName(None, "选择文件", "", file_filter)
        if file:
            self.choose_single_ident_audio_file_result.emit(eid, file, get_video_info(file)["duration"])


    @pyqtSlot(str)
    def choose_folder_and_read_video_and_audio_files(self, eid):
        """选择文件"""
        file = QFileDialog.getExistingDirectory(None, "选择文件夹")
        if file:
            files = batch_scan_folder(file, suffixes=['.mp4', '.mov', '.avi', '.mkv', '.mp3', '.wav', '.flac'])
            self.select_files_result.emit(eid, files, len(files))
            self.select_folder_result.emit(eid, file)

    @pyqtSlot(str)
    def choose_video_and_audio_files(self, eid):
        """选择文件"""
        file_filter = "所有音视频文件 (*.mp4 *.mov *.avi *.mkv *.mp3 *.wav *.m4a *.acc);;MP4 文件 (*.mp4);;MOV 文件 (*.mov);;AVI 文件 (*.avi);;MKV 文件 (*.mkv);; MP3 文件 (*.mp3);; WAV 文件 (*.wav);; M4A 文件 (*.m4a);; ACC 文件 (*.acc)"
        file, _ = QFileDialog.getOpenFileName(None, "选择文件", "", file_filter)
        if file:
            self.select_files_result.emit(eid, [get_video_info(file)], 1)


    @pyqtSlot(str)
    def choose_folder_and_read_video_files(self, eid):
        """选择文件"""
        file = QFileDialog.getExistingDirectory(None, "选择文件夹")
        if file:
            files = batch_scan_folder(file)
            self.select_files_result.emit(eid, files, len(files))
            self.select_folder_result.emit(eid, file)

    @pyqtSlot(str, str)
    def choose_file(self, eid, suffix='mp4'):
        """选择文件"""
        if suffix == 'mp4':
            file_filter = "所有视频文件 (*.mp4 *.mov *.avi *.mkv);;MP4 文件 (*.mp4);;MOV 文件 (*.mov);;AVI 文件 (*.avi);;MKV 文件 (*.mkv)"
        elif suffix == 'audio':
            file_filter = "所有音频文件 (*.mp3 *.wav *.flac);;MP3 文件 (*.mp3);;WAV 文件 (*.wav);;FLAC 文件 (*.flac)"
        elif suffix == 'image':
            file_filter = "所有图片文件 (*.png *.jpg *.jpeg *.bmp);;PNG 文件 (*.png);;JPEG 文件 (*.jpg *.jpeg);;BMP 文件 (*.bmp)"
        else:
            file_filter = "所有文件 (*.*)"
        file, _ = QFileDialog.getOpenFileName(None, "选择文件", "", file_filter)
        if file:
            self.select_folder_result.emit(eid, file)

    @pyqtSlot(str)
    def choose_folder(self, eid):
        """选择文件夹"""
        folder = QFileDialog.getExistingDirectory(None, "选择文件夹")
        if folder:
            self.select_folder_result.emit(eid, folder)

    @pyqtSlot(str, int, str, str)
    def choose_folder_input(self, channel, index, name, suffix):
        """选择文件夹;读取文件夹视频文件数量"""
        folder = QFileDialog.getExistingDirectory(None, "选择文件夹")
        if os.path.isdir(folder):
            if suffix == 'video':
                count = load_file_count(folder)
            elif suffix == 'audio':
                count = load_file_count(folder, suffixes=['.mp3', '.wav', '.flac'])
            else:
                raise Exception("不支持的格式")
            self.select_folder_normal_shot_path_input.emit(channel, index, folder, name, count)

    @pyqtSlot(str, int, str)
    def choose_file_input(self, channel, index, suffix='mp4'):
        """选择文件夹;读取文件夹视频文件数量"""
        file, _ = QFileDialog.getOpenFileName(None, "选择文件", "", f"选择视频文件 (*.{suffix})")
        if os.path.isfile(file):
            self.select_folder_normal_shot_path_input.emit(channel, index, file, file, 1)

    @pyqtSlot(str)
    def auto_mix_folder_input(self, eid):
        """自动混剪选择文件夹"""
        file = QFileDialog.getExistingDirectory(None, "选择文件夹")
        if file:
            files = batch_scan_folder(file)
            duration_items = [file.get("duration") for file in files]
            mix_times = min(duration_items)
            max_times = max(duration_items)
            sum_times = sum(duration_items)
            self.auto_mix_folder_result.emit(eid, file, len(files), mix_times, max_times, sum_times)

    @pyqtSlot(str)
    def batch_ident_and_synthesis(self, suffix):
        """批量识别音频并合成"""
        file = QFileDialog.getExistingDirectory(None, "选择文件夹")
        if file:
            if suffix == 'audio/video':
                file_suffix = ['.mp4', '.mov', '.avi', '.mkv', '.mp3', '.wav', '.flac']
                files = batch_scan_folder(file, file_suffix)
            elif suffix == 'text':
                file_suffix = ['.txt']
                files = load_files(file, file_suffix)
                if files:
                    files = [{"file": file, "duration": 0, "size": os.path.getsize(file)} for file in files]
            else:
                raise Exception("不支持的格式")

            self.batch_ident_and_synthesis_result.emit(json.dumps(files))

    @pyqtSlot(str, int)
    def update_progress(self, pid, progress):
        """更新进度"""
        progress += self.progress_items.get(pid, 0)
        progress = min(progress, 100)
        log.debug(f"更新进度: {pid}, {progress}")
        self.progress_signal.emit(pid, progress)

    ###################  以下为后台任务  ##############


    def _stop_thread(self):
        """停止当前线程"""
        if self.current_thread is not None and self.current_thread.isRunning():
            log.debug(self.current_thread.__dict__)
            self.current_thread.stop()
            self.current_thread = None

    @pyqtSlot()
    def stop(self):
        try:
            self._stop_thread()
        except Exception as e:
            log.error(e)


    @pyqtSlot(str)
    def start_worker(self, text):
        """后台任务"""
        self._stop_thread()
        worker_items = {
            "视频分镜": ClipVideoWorkerThread,
            "视频去重": VideoDeduplicationQtThread,
            "视频合成": VideoSynthesisWorker,
            "音视频分离": AudioAndVideoSeparationWorker,
            "提取音频": ExtractAudioWorker,
            "合并音频": MergeAudioWorker,
        }
        task_items = json.loads(text)
        self.current_thread = worker_items[task_items["task"]](task_items)
        self.current_thread.started.connect(lambda: self.started.emit("开始任务"))
        self.current_thread.finished.connect(lambda: self.finished.emit("任务完成"))
        self.current_thread.progress.connect(lambda pid, progress: self.update_progress(pid, progress))
        self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        self.current_thread.start()

    ############################################################################



    @pyqtSlot(str, str, str)
    def general_write(self, channel, src, desc):
        """通用写作"""
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # self._stop_thread()
        # if not headers.get('Authorization'):
        #     print("请先登录")
        #     self.finished.emit("请先登录")
        #     return
        # self.current_thread = WriteWorkerQtThread(channel, src, desc, headers)
        # self.current_thread.finished.connect(lambda: self.finished.emit("写作结束"))
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.result.connect(lambda result: self.result.emit(result))
        # self.current_thread.start()


    @pyqtSlot(str, str)
    def login(self, username, password):
        """登录"""
        # TODO: 登录
        html_path = resource_path(r"view/index.html")
        self.view.load(QUrl.fromLocalFile(os.path.abspath(html_path)))


        # self._stop_thread()
        # self.current_thread = LoginWorkerQtThread(username, password)
        # self.current_thread.result.connect(self.__init_user_info)
        # self.current_thread.finished.connect(lambda: self.finished.emit("登录成功"))
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.start()


    @pyqtSlot(str)
    def humanize(self, content):
        """通用写作"""
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # self._stop_thread()
        # if not headers.get('Authorization'):
        #     self.finished.emit("请先登录")
        #     print("请先登录")
        #     return
        # self.current_thread = HumanizeWorker(content, headers)
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.result.connect(lambda result: self.result.emit(result))
        # self.current_thread.start()


    @pyqtSlot(str)
    def batch_ident_audio(self, files):
        """批量音视频识别"""
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # self._stop_thread()
        # if not headers.get('Authorization'):
        #     self.finished.emit("请先登录")
        #     print("请先登录")
        #     return
        # self.current_thread = IdentAudioWorkerQtThread(files, headers)
        # self.current_thread.result.connect(lambda result: self.ident_result.emit(result))
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.start()


    @pyqtSlot(str)
    def ident_audio_context(self, file):
        """批量音视频识别"""
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # self._stop_thread()
        # if not headers.get('Authorization'):
        #     self.finished.emit("请先登录")
        #     print("请先登录")
        #     return
        # self.current_thread = IdentAudioContextWorkerQtThread(file, headers)
        # self.current_thread.result.connect(lambda result: self.ident_context_result.emit(result))
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.start()


    @pyqtSlot(str)
    def save_srt_file(self, content):
        """保存srt文件"""
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # if not headers.get('Authorization'):
        #     self.finished.emit("请先登录")
        #     print("请先登录")
        #     return
        # self.current_thread = SaveSrtFileWorkerQtThread(content)
        # self.current_thread.finished.connect(lambda: self.finished.emit("保存srt文件成功"))
        # self.current_thread.result.connect(lambda result: self.result.emit(result))
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.start()


    @pyqtSlot(str)
    def rewrite(self, content):
        """文案重写"""
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # self._stop_thread()
        # if not headers.get('Authorization'):
        #     self.finished.emit("请先登录")
        #     print("请先登录")
        #     return
        # self.current_thread = RewriteWorkerQtThread(content, headers)
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.result.connect(lambda result: self.rewrite_result.emit(result))
        # self.current_thread.start()


    @pyqtSlot()
    def load_audio_model(self):
        """加载音频模型"""
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # self._stop_thread()
        # if not headers.get('Authorization'):
        #     self.finished.emit("请先登录")
        #     print("请先登录")
        #     return
        # self.current_thread = LoadAudioMaterialsWorker(headers)
        # self.current_thread.result.connect(lambda result: self.load_audio_model_result.emit(result))
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.start()

    @pyqtSlot(str)
    def synthesis_audio(self, content):
        print("开始合成音频")
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # self._stop_thread()
        # self.current_thread = SynthesisAudioWorker(content, headers)
        # self.current_thread.result.connect(lambda result: self.result.emit(result))
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.start()


    @pyqtSlot(str)
    def batch_synthesis_or_ident(self, content):
        """批量合成或识别"""
        print("开始批量合成或识别")
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # self._stop_thread()
        # self.current_thread = BatchSynthesisOrIdentWorker(content, headers)
        # self.current_thread.result.connect(lambda result: self.result.emit(result))
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.start()


    @pyqtSlot(str, int)
    def load_audio_video_materials(self, source, page):
        """加载音频视频素材"""
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # self._stop_thread()
        # if not headers.get('Authorization'):
        #     self.finished.emit("请先登录")
        #     print("请先登录")
        #     return
        # self.current_thread = LoadAudioVideoMaterialsWorker(source, page, headers)
        # self.current_thread.result.connect(lambda result: self.source_result.emit(result))
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.start()

    @pyqtSlot(str, int, str, str, str)
    def AiMix_sybthesis(self, file_path, count, output_folder, subtitle, voice):
        """AI合成"""
        # TODO: 功能待更改
        self.finished.emit("此功能待上线")
        return 
        # self._stop_thread()
        # if not headers.get('Authorization'):
        #     self.finished.emit("请先登录")
        #     print("请先登录")
        #     return
        # self.current_thread = AiMixSynthesisWorker(file_path, count, output_folder, subtitle, voice, headers)
        # self.current_thread.result.connect(lambda result: self.result.emit(result))
        # self.current_thread.failed.connect(lambda e: self.failed.emit(e))
        # self.current_thread.start()